﻿using Mapster;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;

namespace Demo.Abp.Extension;

#region 重载
public abstract class CustomCrudAppService<TEntity, TEntityDto, TKey>
    : CustomCrudAppService<TEntity, TEntityDto, TKey, PagedAndSortedResultRequestDto>
    where TEntity : class, IEntity<TKey>
    where TEntityDto : IEntityDto<TKey>
{
    protected CustomCrudAppService(IRepository<TEntity, TKey> repository)
        : base(repository)
    {

    }
}

public abstract class CustomCrudAppService<TEntity, TEntityDto, TKey, TGetListInput>
    : CustomCrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TEntityDto>
    where TEntity : class, IEntity<TKey>
    where TEntityDto : IEntityDto<TKey>
{
    protected CustomCrudAppService(IRepository<TEntity, TKey> repository)
        : base(repository)
    {

    }
}

public abstract class CustomCrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput>
    : CustomCrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput, TCreateInput>
    where TEntity : class, IEntity<TKey>
    where TEntityDto : IEntityDto<TKey>
{
    protected CustomCrudAppService(IRepository<TEntity, TKey> repository)
        : base(repository)
    {

    }
}

public abstract class CustomCrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
    : CustomCrudAppService<TEntity, TEntityDto, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
    where TEntity : class, IEntity<TKey>
    where TEntityDto : IEntityDto<TKey>
{
    protected CustomCrudAppService(IRepository<TEntity, TKey> repository)
        : base(repository)
    {

    }

    protected override Task<TEntityDto> MapToGetListOutputDtoAsync(TEntity entity)
    {
        return MapToGetOutputDtoAsync(entity);
    }

    protected override TEntityDto MapToGetListOutputDto(TEntity entity)
    {
        return MapToGetOutputDto(entity);
    }
}
#endregion


public class CustomCrudAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput,
        TUpdateInput>
    : CrudAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
    where TEntity : class, IEntity<TKey>
    where TGetOutputDto : IEntityDto<TKey>
    where TGetListOutputDto : IEntityDto<TKey>
{
    public CustomCrudAppService(IRepository<TEntity, TKey> repository) : base(repository)
    {
    }
    
    #region Mapster
    protected override TEntity MapToEntity(TCreateInput createInput)
    {
        var entity = createInput.Adapt<TEntity>();
        SetIdForGuids(entity);
        return entity;
    }

    protected override void MapToEntity(TUpdateInput updateInput, TEntity entity)
    {
        if (updateInput is IEntityDto<TKey> entityDto)
        {
            entityDto.Id = entity.Id;
        }
        entity = updateInput.Adapt(entity);
    }

    protected override TGetOutputDto MapToGetOutputDto(TEntity entity)
    {
        return entity.Adapt<TGetOutputDto>(); //ObjectMapper.Map<TEntity, TGetOutputDto>(entity);
    }
    protected override TGetListOutputDto MapToGetListOutputDto(TEntity entity)
    {
        return entity.Adapt<TGetListOutputDto>(); //ObjectMapper.Map<TEntity, TGetListOutputDto>(entity);
    }
    #endregion
}